package nc.tb.ctl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

import nc.tb.cube.CubeView;
import nc.tb.cube.ParaDimVector;
import nc.tb.pub.BusiObj;
import nc.tb.pub.IDimType;
import nc.tb.pub.NtbEnv;
import nc.tb.pub.cache.CacheAccess;
import nc.tb.pub.cache.CacheAccessFactory;
import nc.tb.pub.cache.NtbCacheManager;
import nc.tb.pub.data.INtbCache;
import nc.tb.pub.util.NtbLogger;
import nc.vo.pub.BusinessException;

public class CubeInfoCTL implements INtbCache {
	
	private final static String CACHE_KEY = "CubeInfoCTL";
	
	private ConcurrentHashMap<String,String> hm_cubeCode2Pk;
	private ConcurrentHashMap<String,String> hm_cube2OlapView;
	private ConcurrentHashMap<String,HashMap<String,String>> hm_viewCode2Pk;
	private ConcurrentHashMap<String,String> hm_cubeAndParaDv2PkPlan;
	
	private boolean isOlapViewLoaded = false;

	public void clearCache() {
		hm_cubeCode2Pk.clear();
		hm_cube2OlapView.clear();
		hm_viewCode2Pk.clear();
		hm_cubeAndParaDv2PkPlan.clear();
		isOlapViewLoaded = false;
		cubeInforCTL = null;
	}
	
	private CubeInfoCTL() {
		hm_cubeCode2Pk = new ConcurrentHashMap<String,String>();
		hm_cube2OlapView = new ConcurrentHashMap<String,String>();
		hm_viewCode2Pk = new ConcurrentHashMap<String,HashMap<String,String>>();
		hm_cubeAndParaDv2PkPlan = new ConcurrentHashMap<String,String>();
	}
	
	private static CubeInfoCTL cubeInforCTL = null;
	public static CubeInfoCTL getInstance() {
		if (NtbEnv.isUICall) {
			if(cubeInforCTL == null) {
				cubeInforCTL = new CubeInfoCTL();
				NtbCacheManager.putCacheInstance(CACHE_KEY, cubeInforCTL);
			}
			return cubeInforCTL;
		}
		CubeInfoCTL inst = (CubeInfoCTL)NtbCacheManager.getCacheInstance(CACHE_KEY);
		if(inst== null) {
			inst = new CubeInfoCTL();
			NtbCacheManager.putCacheInstance(CACHE_KEY, inst);
		}
		return inst;
	}
	
	public String getViewPk(String pkCube, String codeView) {
		HashMap<String,String> hm = hm_viewCode2Pk.get(pkCube);
		return hm==null ? null : hm.get(codeView);
	}
	public void puViewPk(String pkCube, String codeView, String pk) {
		HashMap<String,String> hm = hm_viewCode2Pk.get(pkCube);
		if (hm == null) {
			hm = new HashMap<String,String>();
			hm_viewCode2Pk.put(pkCube, hm);
		}
		hm.put(codeView, pk);
	}
	public void removeViewCode(String pkCube, String codeView) {
		HashMap<String,String> hm = hm_viewCode2Pk.get(pkCube);
		if (hm != null)
			hm.remove(codeView);
	}
	public void removeAllViewCode(String pkCube) {
		hm_viewCode2Pk.remove(pkCube);
	}
	public void removeAllViewCode() {
		hm_viewCode2Pk.clear();
	}
	
	public void removeCode(String objcode) {
		hm_cubeCode2Pk.remove(objcode);
	}
	public String getPk(String objcode) {
		return hm_cubeCode2Pk.get(objcode);
	}
	public void putValue(String objcode, String primarykey) {
		hm_cubeCode2Pk.put(objcode, primarykey);
	}
	
	public void setCubeOlapView(String pk_cube, String pk_olapView) {
		hm_cube2OlapView.put(pk_cube, pk_olapView);
	}
	public String getOlapViewPk(String pk_cube) {
		if (!isOlapViewLoaded)
			loadOlapViews();
		return hm_cube2OlapView.get(pk_cube);
	}
	
	public void setPkPlan(String pk_cube, ParaDimVector pdv, String pk_plan) {
		hm_cubeAndParaDv2PkPlan.put(getKey(pk_cube, pdv), pk_plan);
	}
	public String getPkPlan(String pk_cube, ParaDimVector pdv) {
		return hm_cubeAndParaDv2PkPlan.get(getKey(pk_cube, pdv));
	}
	public void removePkPlan(String pk_cube, ParaDimVector pdv) {
		hm_cubeAndParaDv2PkPlan.remove(getKey(pk_cube, pdv));
	}
	private static String getKey(String pk_cube, ParaDimVector pdv) {
		return (pdv==null) ? pk_cube : pk_cube + pdv.toPkString();
	}
	
	public String[] getAllPks() {
		String[] result = hm_cubeCode2Pk == null ? new String[0] : new String[hm_cubeCode2Pk.size()];
		Iterator<String> it = hm_cubeCode2Pk.values().iterator();
		int idx = 0;
		while (it.hasNext()) {
			result[idx] = it.next();
			idx++;
		}
		return result;
	}
	
	public void loadOlapViews() {
		if (isOlapViewLoaded)
			return;
		try {
			BusiObj[] bos = SheetObjectCTL.queryBusiObjByCond(IDimType.CUBEVIEW, " objcode='001'");
			if (bos != null && bos.length > 0) {
				CacheAccess ca = CacheAccessFactory.getCacheAccess();
				for (int i=0; i<bos.length; i++) {
					if (bos[i] != null && bos[i] instanceof CubeView) {
						CubeView cv = (CubeView)bos[i];
						setCubeOlapView(cv.getPk_Cube(), cv.getPrimaryKey());
						puViewPk(cv.getPk_Cube(), cv.getObjcode(), cv.getPrimaryKey());
						CubeView so = (CubeView) ca.get(cv.getPrimaryKey());
						if (so != null) {
							so.copyFrom(cv);
							cv = so;
						}
						else
							ca.put(cv.getPrimaryKey(), cv);
					}
				}
			}
			isOlapViewLoaded = true;
		}
		catch (BusinessException be) {
			NtbLogger.printException(be);
		}
	}
}
